import React, { Component } from 'react'
import styles from './index.module.scss'
import { Flex, PickerView } from 'antd-mobile'
import classNames from 'classnames'
import { getHouseCondition } from '../../api/filter'
import { getCurrentCity } from '../../utils/city'
import FilterFooter from '../FilterFooter'
import { Spring } from 'react-spring/renderprops'

export default class Filter extends Component {
  constructor () {
    super ()

    this.state = {
      openType: '', // 点击或者打开的类型
      // 标题的某一项选中，是否高亮
      selectedTypeTitle: {
        area: false,
        mode: false,
        price: false,
        more: false
      },
      // 最终的筛选数据，并传递给父组件HouseList，通过父组件发送ajax请求实现筛选功能
      // 所以只有点击确定之后才能更改这个selectValue的数据，其他时候不能改
      selectValue: {
        area: ['area', 'null'],
        mode: ['null'],
        price: ['null'],
        more: []
      },
      // 两组暂存筛选数据，分别有两个视图PickerView和MoreView，两个确定按钮分别控制
      // 第一组是区域、方式、租金组
      tempPickerViewValue: {
        area: ['area', 'null'],
        mode: ['null'],
        price: ['null']
      },
      // 第二组是筛选组
      tempMoreValue: [],
      
      houseCondition: null // 房屋筛选的条件
    }
  }


  types = [
    {
      type: 'area',
      name: '区域'
    },
    {
      type: 'mode',
      name: '方式'
    },
    {
      type: 'price',
      name: '租金'
    },
    {
      type: 'more',
      name: '筛选'
    },
  ]

  /**
   * 处理高亮显示
   * 通过最终数据selectValue中选中的值，来决定高亮状态selectedTypeTitle
   * 逻辑是只要 selectValue 的值不是默认值，就是高亮状态，表示被选择过
   */
  dealWithHighLight = () => {
    const { selectValue } = this.state
    let tempObj = {}
    Object.keys(selectValue).forEach(item => {
      if (item === 'area') {
        tempObj['area'] = selectValue.area.length >= 2 && selectValue.area[1] !== 'null'
      } else if (item === 'mode') {
        tempObj['mode'] = selectValue.mode.length > 0 && selectValue.mode[0] !== 'null'
      } else if (item === 'price') {
        tempObj['price'] = selectValue.price.length > 0 && selectValue.price[0] !== 'null'
      } else if (item === 'more') {
        tempObj['more'] = selectValue.more.length > 0
      }
    })

    // 被选择过就高亮
    this.setState({
      selectedTypeTitle: tempObj
    })
  }

  componentDidMount () {
    this.getHouseConditionData()
  }

  // 获取房屋筛选的数据
  getHouseConditionData = async () => {
    const { value } = await getCurrentCity()
    const res = await getHouseCondition(value)

    this.setState({
      houseCondition: res.data.body
    })
  }

  clickType = type => {
    const { selectedTypeTitle } = this.state
    this.setState({
      openType: type,
      selectedTypeTitle: {
        // 扩展运算符的作用是修改对象里面某一个key的value值时，不影响别的键值对，要修改的键直接覆盖即可
        ...selectedTypeTitle,
        [type]: true
      }
    })
  }

  // 类型标题部分
  renderTypeTitle = () => {
    const { selectedTypeTitle } = this.state
    return (
      <Flex className={styles.filterTitle}>
      {this.types.map(item => {
        // 决定遍历到item这一项是否高亮显示
        const isSelect = selectedTypeTitle[item.type]
        return (
          <Flex.Item key={item.type}>
            <span className={classNames(styles.dropdown, {
              // 属性表达式，按照isSelect的值来决定是否有该属性对应的类
              [styles.selected]: isSelect})}
              onClick={() => this.clickType(item.type)}>
                <span>{item.name}</span>
                <i className='iconfont icon-arrow'></i>
            </span>
          </Flex.Item>
        )
      })}
    </Flex>
    )
  }

  // 取消遮罩
  cancelMask = () => {
    this.setState({
      selectedTypeTitle: {
        [this.state.openType]: false
      }
    },
    // 修改完选中项以后再去取消高亮状态数据
    () => {
      this.setState({
        openType: ''
      },
      // 确保修改完数据以后再处理高亮状态
      () => {
        this.dealWithHighLight()
      })
    })
  }

  // 渲染遮罩
  renderMask = () => {
    const { openType } = this.state
    const isShow = openType === 'area' || openType === 'mode' || openType === 'price'

    // if (!isShow) return null

    // return <div className={styles.mask} onClick={this.cancelMask}></div>
    // 遮罩出现动画，透明度渐变动画，第三方包react-spring实现
    return (
      <Spring to={{ opacity: isShow ? 1 : 0 }} config={{ duration: 250}}>
        {props => {
          if (props.opacity === 0) {
            return null
          }
          return (
            <div
              onClick={this.cancelMask}
              style={{ opacity: props.opacity }}
              className={styles.mask}></div>
          )
        }}
      </Spring>
    )
  }

  onChange = value => {
    const { tempPickerViewValue, openType } = this.state

    // 修改选择器的暂存数据openType，不影响对象内其他数据
    this.setState({
      tempPickerViewValue: {
        ...tempPickerViewValue,
        [openType]: value
      }
    })
  }

  // 渲染选择器
  renderPickerView = () => {
    const {openType, selectValue, tempPickerViewValue, houseCondition: {area, subway, rentType, price}} = this.state

    let data = null
    let cols = 3

    switch (openType) {
      case 'area':
        data = [area,subway]
        cols = 3
        break;
      case 'mode':
        data = rentType
        cols = 1
        break;
      case 'price':
        data = price
        cols = 1
        break;
      default:
        break;
    }

    // 取出设置好的值，设置给pickerview的value
    const value = tempPickerViewValue[openType]

    return (
      <div>
        {/* 通过受控组件的value属性和onChange事件实现数据的双向绑定，相当于vue的v-model */}
        <PickerView data={data} cols={cols} value={value} onChange={this.onChange}></PickerView>
        <FilterFooter
          onCancel={() => this.cancelMask()}
          onOk={() => {
            this.setState({
              selectValue: {
                ...selectValue,
                [openType]: tempPickerViewValue[openType]
              }
            },
            () => {
              this.setState({
                openType: ''
              },
              () => {
                // 对状态做最后一次高亮处理
                this.dealWithHighLight()
                // 把最终的值传递给父组件
                this.props.onConditionChange(this.state.selectValue)
              })
            })
          }}></FilterFooter>
      </div>
    )
  }

  // 切换选择
  toggleSelect = value => {
    let oldTempMoreValue = this.state.tempMoreValue

    if (oldTempMoreValue.includes(value)) {
      // 之前有
      oldTempMoreValue = oldTempMoreValue.filter(item => item !== value)
    } else {
      // 之前没有
      oldTempMoreValue.push(value)
    }

    this.setState({
      tempMoreValue: oldTempMoreValue
    })
  }

  renderEveryItem = (title, data) => {
    const { tempMoreValue } = this.state
    return (
      <>
        <dt className={styles.dt}>{title}</dt>
        <dd className={styles.dd}>
          {data.map(item => {
            return (
              <span
                key={item.value}
                className={classNames(styles.tag, {
                  [styles.tagActive]: tempMoreValue.includes(item.value)
                })}
                onClick={() => this.toggleSelect(item.value)}>
                  {item.label}
                </span>
            )
          })}
        </dd>
      </>
    )
  }

  renderMoreView = () => {
    const {
      roomType,
      oriented,
      floor,
      characteristic
    } = this.state.houseCondition
    const { selectValue, tempMoreValue } = this.state

    return (
      <div className={styles.filterMore}>
        <div
          className={styles.filterMoreMask}
          onClick={() => this.cancelMask()}></div>
        <div className={styles.tags}>
          <dl className={styles.dl}>
            {/* 户型 */}
            {this.renderEveryItem('户型', roomType)}
            {/* 朝向 */}
            {this.renderEveryItem('朝向', oriented)}
            {/* 楼层 */}
            {this.renderEveryItem('楼层', floor)}
            {/* 房屋亮点 */}
            {this.renderEveryItem('房屋亮点', characteristic)}
          </dl>
        </div>
        <div className={styles.filterMoreFooter}>
          <FilterFooter
            cancelText='清除'
            onCancel={() => {
              this.setState({
                tempMoreValue: []
              })
            }}
            onOk={() => {
              this.setState({
                selectValue: {
                  ...selectValue,
                  more: tempMoreValue
                }
              },
              () => {
                this.setState({
                  openType: ''
                },
                () => {
                  this.dealWithHighLight()
                  this.props.onConditionChange(this.state.selectValue)
                })
              })
            }}></FilterFooter>
        </div>
      </div>
    )
  }

  render() {
    const { houseCondition, openType } = this.state
    return (
      <div className={styles.root}>
        {this.renderMask()}
        <div className={styles.content}>
          {/* 渲染标题 */}
          {this.renderTypeTitle()}
          {/* 渲染选择器 */}
          {houseCondition && 
            (openType === 'area' || 
            openType === 'mode' || 
            openType === 'price') && 
            this.renderPickerView()}
          {/* 渲染右边的MoreView */}
          {houseCondition && openType === 'more' && this.renderMoreView()}
        </div>
      </div>
    )
  }
}
